/* $Id:person.h $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#ifndef __PERSON_H
#define __PERSON_H

#include <string>
#include <map>
#include <list>
using namespace std;

#include "background_level.h"
#include "skill_level.h"
#include "has_special.h"
#include "stat_amount.h"
#include "person_items.h"
#include "status.h"
#include "relations.h"

#define loopPersonBackground(r,v) loopSingle((r)->listBackground(),v,class background_level,list)
#define loopPersonSkills(r,v) loopMap((r)->listSkills(),v,class skill_level)
#define loopPersonSpecials(r,v) loopMap((r)->listSpecials(),v,class has_special)
#define loopPersonStats(r,v) loopMap((r)->listStats(),v,class stat_amount)
#define loopPersonItems(r,v) loopSingle((r)->listItems(),v,class person_items,list)
#define loopPersonStatus(r,v) loopMap((r)->listStatus(),v,class status)
#define loopPersonRelations(r,v) loopMap((r)->listRelations(),v,class relations)

class person {
    string name;
    string user;
    class race *race;
    map<string,class background_level> background;
    map<string,class skill_level> skills;
    map<string,class has_special> specials;
    map<string,class stat_amount> stats;
    map<string,class person_items> items;
    map<string,class status> status;
    int points;
    map<string,class relations> relations;
    int location;
    int start; // when was this player last logon or this npc created
    int last; // last command to this character by the player or the last ncp command
public:
    person();

    // Field : name
    const string getName() const;
    void setName(const string v);

    // Field : user
    const string getUser() const;
    void setUser(const string v);

    // Field : race
    class race& getRace() const;
    void setRace(class race &v);

    // Field : background
    class background_level& getBackground(const string v);
    list<class background_level>& listBackground();
    void setBackground(class background_level &v);
    void delBackground(const string v);
    const bool isBackground(const string v) const;

    // Field : skills
    class skill_level& getSkills(const string v);
    map<string,class skill_level>& listSkills();
    void setSkills(class skill_level &v);
    void delSkills(const string v);
    const bool isSkills(const string v) const;

    // Field : specials
    class has_special& getSpecials(const string v);
    map<string,class has_special>& listSpecials();
    void setSpecials(class has_special &v);
    void delSpecials(const string v);
    const bool isSpecials(const string v) const;

    // Field : stats
    class stat_amount& getStats(const string v);
    map<string,class stat_amount>& listStats();
    void setStats(class stat_amount &v);
    void delStats(const string v);
    const bool isStats(const string v) const;

    // Field : items
    class person_items& getItems(const string v);
    list<class person_items>& listItems();
    void setItems(class person_items &v);
    void delItems(const string v);
    const bool isItems(const string v) const;

    // Field : status
    class status& getStatus(const string v);
    map<string,class status>& listStatus();
    void setStatus(class status &v);
    void delStatus(const string v);
    const bool isStatus(const string v) const;

    // Field : points
    const int getPoints() const;
    void setPoints(const int v);

    // Field : relations
    class relations& getRelations(const string v);
    map<string,class relations>& listRelations();
    void setRelations(class relations &v);
    void delRelations(const string v);
    const bool isRelations(const string v) const;

    // Field : location
    const int getLocation() const;
    void setLocation(const int v);
    const string showLocation() const;

    // Field : start
    const int getStart() const;
    void setStart(const int v);

    // Field : last
    const int getLast() const;
    void setLast(const int v);

    void save(class channel &ch);
    void load(class channel &ch);
    void xml(ofstream &f, int l=0, int r=0);
};

// Repository

#define loopPersons(v) loopMap(person_repo.listPerson(),v,class person)

class personRepository {
    map<string,person> persons;
public:
    class person& getPerson(const string v);
    void setPerson(class person& v);
    map<string,class person>& listPerson();
    void delPerson(const string v);
    const bool isPerson(const string v) const;
    multimap<string, sigc::signal<void, class person& > > relations;
    bool load(class channel &ch);
    void save(class channel &ch);
};

extern personRepository person_repo;

#endif // __PERSON_H
